package cn.liyunqi.prplug.util;

import cn.liyunqi.prplug.view.AlertUtil;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import oshi.SystemInfo;
import oshi.hardware.Baseboard;
import oshi.hardware.HardwareAbstractionLayer;

import javax.crypto.Cipher;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.image.BufferedImage;
import java.io.*;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class PrPlugUtil {

    public static final String PUBLIC_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMicGQMF5ffdSc1DMwWNFvn6JfV/7zwe5RVognO1BhwJXZSJkVqK6TupMiUn/wPmCFNNDcARta89K9o4gEVVy2UCAwEAAQ==";
    public static final String effectData = "[\"立方体旋转\",\"交叉划像\",\"圆划像\",\"盒形划像\",\"菱形划像\",\"划出\",\"双侧平推门\",\"带状擦除\",\"插入\",\"时钟式擦除\",\"棋盘擦除\",\"楔形擦除\",\"水波块\",\"油漆飞溅\",\"螺旋框\",\"随机擦除\",\"风车\",\"光圈擦除\",\"光线\",\"漏光\",\"球形模糊\",\"色度泄漏\",\"默比乌斯缩放\",\"交叉溶解\",\"白场过渡\",\"胶片溶解\",\"非叠加溶解\",\"黑场过渡\",\"中心拆分\",\"带状滑动\",\"交叉缩放\",\"翻页\"]";

    private static final String APP_TYPE = "PR-PLUG";

    //非对称密钥算法
    public static final String KEY_ALGORITHM="RSA";

    public static boolean isEmpty(Object temp){
        if(temp == null){
            return true;
        }
        return temp.toString().trim().isEmpty();
    }

    public static String getValueFromFile(String path){
        File file = new File(path);
        return getValueFromFile(file);
    }

    public static String getValueFromFile(File file){

        if(!file.exists()){
            return null;
        }

        String temp = "";
        try {
            FileInputStream in = new FileInputStream(file);
            Reader reader = new InputStreamReader(in);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String line;

            while((line=bufferedReader.readLine())!=null){
                temp = temp + line;
            }
            bufferedReader.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return temp;
    }

    public static boolean isDouble(Object temp){

        if(isEmpty(temp)){
            return false;
        }
        try {
            Double.valueOf(temp.toString());
            return true;
        }catch (Exception ex){
            return false;
        }
    }

    public static String safeValue(Object temp) {
        if(temp == null){
            return "";
        }else{
            return temp.toString().trim();
        }
    }



    /**
     * 从剪贴板中获取文本（粘贴）
     */
    public static String getClipboardString() {

        // 获取系统剪贴板
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        // 获取剪贴板中的内容
        Transferable trans = clipboard.getContents(null);

        if (trans != null) {
            // 判断剪贴板中的内容是否支持文本
            if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                try {
                    // 获取剪贴板中的文本内容
                    String text = (String) trans.getTransferData(DataFlavor.stringFlavor);
                    return text;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    /**
     * 把文本设置到剪贴板（复制）
     */
    public static void setClipboardString(String text) {
        // 获取系统剪贴板
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        // 封装文本内容
        Transferable trans = new StringSelection(text);
        // 把文本内容设置到系统剪贴板
        clipboard.setContents(trans, null);
    }

    public static void main(String[] args) throws Exception {
        //findOCR(new File("F:\\workspace\\pr-plug-java\\pr-plug-data\\materialDist.png"));
        //System.out.println(getClipboardString());
        //String sn = getHardDiskSN("D");
        //System.out.println("***硬盘编号***");
        //System.out.println(getBaseboardSerialNumber());

    }

    public static String getBaseboardSerialNumber(){

        SystemInfo si = new SystemInfo();

        HardwareAbstractionLayer hal = si.getHardware();

        final Baseboard baseboard = hal.getComputerSystem().getBaseboard();

        return MD5Util.get32BitMd5EncString(baseboard.getManufacturer()) + "-" + baseboard.getSerialNumber();
    }

    /**
     * 公钥加密
     * @param data 待加密数据
     * @param key 密钥
     * @return String 加密数据
     * */
    public static String encryptRSAByPublicKey(String data,String key) throws Exception{

        return Base64.encode(encryptRSAByPublicKey(data.getBytes(),Base64.decode(key)));
    }
    public static byte[] encryptRSAByPublicKey(byte[] data,byte[] key) throws Exception{

        //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);

        //数据加密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    public static int authApp(String sn){

        String workId = UUID.randomUUID().toString();

        String unitCode = getBaseboardSerialNumber();

        Map<String,String> request = new HashMap<>();

        request.put("workId",workId);
        request.put("unitCode",unitCode);
        request.put("appType",APP_TYPE);
        request.put("sn",sn);


        //1.打开浏览器
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        //2.声明get请求
        HttpPost httpPost = new HttpPost("http://app-auth.liyunqi.cn:7000/authApp");
        //4.判断状态码
        try {

            //设置签名
            String requestStr = JSONObject.toJSONString(request);

            String md5 = MD5Util.get32BitMd5EncString(requestStr);

            String sign = encryptRSAByPublicKey(md5,PUBLIC_KEY);

            //只需要16位的密码
            String aesPassword = UUIDUtil.getUUID().substring(0,16);

            //body加密
            String body = AESUtil.Encrypt(requestStr,aesPassword);

            //密码加密
            String aesKeySecert = encryptRSAByPublicKey(aesPassword,PUBLIC_KEY);

            StringEntity entity = new StringEntity(body);
            httpPost.setEntity(entity);
            httpPost.addHeader("Authentication",sign);
            httpPost.addHeader("SecurityKey",aesKeySecert);
            //5.发送请求
            response = httpClient.execute(httpPost);

            if(response.getStatusLine().getStatusCode()==200){
                HttpEntity responseEntity = response.getEntity();
                String string = EntityUtils.toString(responseEntity, "utf-8");

                if(!PrPlugUtil.isEmpty(string)){
                    //解码
                    JSONObject responseJson = JSONObject.parseObject(AESUtil.Decrypt(string,aesPassword));

                    if("0000".equals(responseJson.getString("status"))){
                        if(!workId.equals(responseJson.getString("workId"))){
                            AlertUtil.showErrorAlert("验证异常");
                        }else{
                            return 0;
                        }
                    }else{
                        AlertUtil.showErrorAlert(responseJson.getString("msg"));
                    }
                }else{
                    AlertUtil.showErrorAlert("网络异常");
                }
            }else{
                AlertUtil.showErrorAlert("网络异常");
            }


        } catch (UnsupportedEncodingException e) {
            AlertUtil.showWarnAlert("验证异常");
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            AlertUtil.showWarnAlert("验证异常");
            e.printStackTrace();
        } catch (IOException e) {
            AlertUtil.showWarnAlert("验证异常");
            e.printStackTrace();
        } catch (Exception e) {
            AlertUtil.showWarnAlert("验证异常");
            e.printStackTrace();
        } finally {
            //6.关闭资源
            if(response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(httpClient != null){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return 1;
    }
}
